package com.zhentao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhentao.dto.FaceLoginDTO;
import com.zhentao.dto.FaceRegisterDTO;
import com.zhentao.dto.FaceRecognitionDTO;
import com.zhentao.pojo.UserFaceInfo;
import com.zhentao.service.UserFaceInfoService;
import com.zhentao.mapper.UserFaceInfoMapper;
import com.zhentao.util.FaceEngineUtil;
import com.zhentao.util.MinioUtil;
import com.zhentao.vo.FaceLoginVO;
import com.zhentao.vo.FaceRegisterVO;
import com.zhentao.vo.FaceRecognitionVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
* @author Administrator
* @description 针对表【user_face_info】的数据库操作Service实现
* @createDate 2025-09-02 15:19:14
*/
@Slf4j
@Service
public class UserFaceInfoServiceImpl extends ServiceImpl<UserFaceInfoMapper, UserFaceInfo>
    implements UserFaceInfoService{

    @Autowired
    private FaceEngineUtil faceEngineUtil;

    @Autowired
    private MinioUtil minioUtil;

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public FaceRegisterVO faceRegister(FaceRegisterDTO registerDTO) {
        try {
            // 处理人脸图片
            MultipartFile faceImage = registerDTO.getFaceImage();
            if (faceImage.isEmpty()) {
                throw new RuntimeException("人脸图片不能为空");
            }

            // 提取人脸特征
            byte[] faceFeature = faceEngineUtil.extractFaceFeature(faceImage.getBytes());

            // 检查人脸是否已注册（与已有人脸特征对比）
            List<UserFaceInfo> allUsers = this.list();
            for (UserFaceInfo user : allUsers) {
                if (user.getFaceFeature() != null) {
                    if (faceEngineUtil.isFaceMatch(faceFeature, user.getFaceFeature())) {
                        throw new RuntimeException("该人脸已注册，用户ID：" + user.getId());
                    }
                }
            }

            // 保存人脸图片
            String imagePath = saveImage(faceImage);

            // 创建用户信息
            UserFaceInfo userFaceInfo = new UserFaceInfo();
            
            // 生成唯一标识
            String faceId = UUID.randomUUID().toString().replace("-", "");
            
            userFaceInfo.setFaceId(faceId);
            userFaceInfo.setName(null); // 不设置姓名
            userFaceInfo.setFaceFeature(faceFeature);
            userFaceInfo.setFpath(imagePath);
            userFaceInfo.setCreateTime(new Date());
            userFaceInfo.setUpdateTime(new Date());

            // 保存到数据库
            this.save(userFaceInfo);

            // 构建返回结果
            FaceRegisterVO registerVO = new FaceRegisterVO();
            registerVO.setId(userFaceInfo.getId());
            registerVO.setFaceId(faceId);
            registerVO.setName(null); // 不返回姓名
            registerVO.setCreateTime(DATE_FORMAT.format(new Date()));
            registerVO.setImagePath(imagePath);

            log.info("用户人脸注册成功，人脸ID: {}", faceId);
            return registerVO;

        } catch (Exception e) {
            log.error("人脸注册失败", e);
            throw new RuntimeException("人脸注册失败: " + e.getMessage());
        }
    }

    @Override
    public FaceLoginVO faceLogin(FaceLoginDTO loginDTO) {
        try {
            // 处理人脸图片
            MultipartFile faceImage = loginDTO.getFaceImage();
            if (faceImage.isEmpty()) {
                throw new RuntimeException("人脸图片不能为空");
            }

            // 提取人脸特征
            byte[] loginFaceFeature = faceEngineUtil.extractFaceFeature(faceImage.getBytes());

            // 查询所有用户
            List<UserFaceInfo> users = this.list();
            log.info("登录时查询到用户数量: {}", users.size());
            for (UserFaceInfo user : users) {
                log.info("用户信息: ID={}, Name={}, FaceId={}", user.getId(), user.getName(), user.getFaceId());
            }

            // 如果没有任何用户，提示先注册
            if (users.isEmpty()) {
                throw new RuntimeException("系统中暂无用户，请先进行人脸注册");
            }

            // 遍历用户进行人脸匹配
            UserFaceInfo matchedUser = null;
            float maxSimilarity = 0f;

            for (UserFaceInfo user : users) {
                if (user.getFaceFeature() != null) {
                    float similarity = faceEngineUtil.compareFaceFeature(loginFaceFeature, user.getFaceFeature());
                    if (similarity > maxSimilarity) {
                        maxSimilarity = similarity;
                        matchedUser = user;
                    }
                }
            }

            // 判断是否匹配成功
            if (matchedUser != null && faceEngineUtil.isFaceMatch(loginFaceFeature, matchedUser.getFaceFeature())) {
                // 找到匹配用户，直接登录
                FaceLoginVO loginVO = new FaceLoginVO();
                BeanUtils.copyProperties(matchedUser, loginVO);
                loginVO.setSimilarity(maxSimilarity);
                loginVO.setLoginTime(DATE_FORMAT.format(new Date()));

                log.info("用户人脸登录成功: {}, 相似度: {}", matchedUser.getName(), maxSimilarity);
                return loginVO;
            } else {
                // 未找到匹配用户，登录失败
                log.warn("人脸登录失败：未找到匹配的用户，最高相似度: {}", maxSimilarity);
                throw new RuntimeException("人脸登录失败：未找到匹配的用户，请先进行人脸注册");
            }

        } catch (Exception e) {
            log.error("人脸识别失败", e);
            throw new RuntimeException("人脸识别失败: " + e.getMessage());
        }
    }

    @Override
    public UserFaceInfo findByFaceId(String faceId) {
        LambdaQueryWrapper<UserFaceInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserFaceInfo::getFaceId, faceId);
        return this.getOne(queryWrapper);
    }

    @Override
    public UserFaceInfo findByName(String name) {
        LambdaQueryWrapper<UserFaceInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserFaceInfo::getName, name);
        return this.getOne(queryWrapper);
    }

    @Override
    public FaceRecognitionVO faceRecognition(FaceRecognitionDTO recognitionDTO) {
        try {
            // 处理人脸图片
            MultipartFile faceImage = recognitionDTO.getFaceImage();
            if (faceImage.isEmpty()) {
                throw new RuntimeException("人脸图片不能为空");
            }

            // 提取人脸特征
            byte[] faceFeature = faceEngineUtil.extractFaceFeature(faceImage.getBytes());

            // 查询所有用户
            List<UserFaceInfo> users = this.list();

            // 遍历用户进行人脸匹配
            UserFaceInfo matchedUser = null;
            float maxSimilarity = 0f;

            for (UserFaceInfo user : users) {
                if (user.getFaceFeature() != null) {
                    float similarity = faceEngineUtil.compareFaceFeature(faceFeature, user.getFaceFeature());
                    if (similarity > maxSimilarity) {
                        maxSimilarity = similarity;
                        matchedUser = user;
                    }
                }
            }

            // 判断是否匹配成功
            if (matchedUser != null && faceEngineUtil.isFaceMatch(faceFeature, matchedUser.getFaceFeature())) {
                // 找到匹配用户，直接登录
                FaceRecognitionVO recognitionVO = new FaceRecognitionVO();
                BeanUtils.copyProperties(matchedUser, recognitionVO);
                recognitionVO.setSimilarity(maxSimilarity);
                recognitionVO.setAction("login");
                recognitionVO.setActionTime(DATE_FORMAT.format(new Date()));
                recognitionVO.setIsNewUser(false);

                log.info("用户登录成功: {}, 相似度: {}", matchedUser.getName(), maxSimilarity);
                return recognitionVO;
            } else {
                // 未找到匹配用户，识别失败
                log.warn("人脸识别失败：未找到匹配的用户，最高相似度: {}", maxSimilarity);
                throw new RuntimeException("人脸识别失败：未找到匹配的用户，请先进行人脸注册");
            }

        } catch (Exception e) {
            log.error("人脸识别失败", e);
            throw new RuntimeException("人脸识别失败: " + e.getMessage());
        }
    }

    /**
     * 保存人脸图片到MinIO
     * 
     * @param file 图片文件
     * @return MinIO访问URL
     */
    private String saveImage(MultipartFile file) throws IOException {
        return minioUtil.uploadFaceImage(file);
    }

    @Override
    public boolean deleteUser(Integer id) {
        try {
            // 先查询用户信息
            UserFaceInfo userInfo = this.getById(id);
            if (userInfo == null) {
                return false;
            }

            // 删除数据库记录
            boolean removed = this.removeById(id);
            
            if (removed && userInfo.getFpath() != null) {
                // 删除存储的图片
                deleteStoredImage(userInfo.getFpath());
            }
            
            return removed;

        } catch (Exception e) {
            log.error("删除用户失败，ID: {}", id, e);
            return false;
        }
    }

    /**
     * 从MinIO删除图片
     * 
     * @param imageUrl 图片URL
     */
    private void deleteStoredImage(String imageUrl) {
        try {
            String objectName = minioUtil.extractObjectName(imageUrl);
            if (objectName != null) {
                minioUtil.deleteObject(objectName);
                log.info("从MinIO删除图片成功: {}", objectName);
            }
        } catch (Exception e) {
            log.warn("从MinIO删除图片失败: {}", imageUrl, e);
        }
    }
}




